package com.zhiwei.tool;

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;
import java.util.zip.GZIPOutputStream;

public class Utils {

    private static final String SALT = "dR4&*2Ux@#N3";

    private static String[] chars = new String[]{"a", "b", "c", "d", "e", "f",
            "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s",
            "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5",
            "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I",
            "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
            "W", "X", "Y", "Z"};

    private Utils() {
        throw new AssertionError("ObjUtils cannot be instantiated!");
    }

    public static void main(String[] args) {
        System.out.println(chars.length);

    }

    /**
     * 判断空
     *
     * @param pObj
     * @return
     */
    public static boolean isNull(Object pObj) {
        if (pObj == null) {
            return true;
        } else {
            if (pObj instanceof String) {
                if (((String) pObj).length() == 0) {
                    return true;
                }
            } else if (pObj instanceof Collection) {
                if (((Collection) pObj).size() == 0) {
                    return true;
                }
            } else if (pObj instanceof Map && ((Map) pObj).size() == 0) {
                return true;
            }
            return false;
        }
    }

    /**
     * 判断非空
     *
     * @param pObj
     * @return
     */
    public static boolean notNull(Object pObj) {
        return !isNull(pObj);
    }

    /**
     * 判断是否存在空值
     *
     * @param objs
     * @return
     */
    public static boolean isAnyNull(Object... objs) {
        if (objs != null) {
            for (Object obj : objs) {
                if (isNull(obj)) {
                    return true;
                }
            }
        } else {
            return true;
        }
        return false;
    }

    /**
     * 判断 全部 非空
     *
     * @param objs
     * @return
     */
    public static boolean noneNull(Object... objs) {
        return !isAnyNull(objs);
    }

    /**
     * 判断对象的 class 是否匹配
     *
     * @param obj    需要验证的对象
     * @param tClass 目标类型
     * @param <T>
     * @return
     */
    public static <T> boolean matchClass(Object obj, Class<T> tClass) {
        Class aClass = obj.getClass();//获取这个类的所以接口类数组
        return tClass.equals(aClass);
    }

    /**
     * 流水号生成方法
     *
     * @return
     */
    public static String uid() {
        StringBuilder shortBuffer = new StringBuilder();
        String uuid = System.currentTimeMillis() + UUID.randomUUID().toString().replace("-", "");
        for (int i = 0; i < 15; i++) {
            String str = uuid.substring(i * 3, i * 3 + 3);
            int x = Integer.parseInt(str, 16);
            shortBuffer.append(chars[x % 0x3E]);
        }
        return shortBuffer.toString();
    }

    public static String md5Uid(String md5) {
        StringBuilder shortBuffer = new StringBuilder();
        for (int i = 0; i < 8; i++) {
            String str = md5.substring(i * 4, i * 4 + 4);
            int x = Integer.parseInt(str, 16);
            shortBuffer.append(chars[x % 0x3E]);
        }
        return shortBuffer.toString();
    }

    /**
     * 加密算法
     *
     * @param str
     * @return
     */
    public static String encoding(String str) {
        Mac mac = null;
        byte[] text = null;
        try {
            byte[] data = SALT.getBytes(StandardCharsets.ISO_8859_1);
            SecretKey secretKey = new SecretKeySpec(data, "HmacSHA1");
            mac = Mac.getInstance("HmacSHA1");
            mac.init(secretKey);
            text = str.getBytes(StandardCharsets.ISO_8859_1);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new String(mac.doFinal(text));
    }

    /**
     * 创建文件
     *
     * @param file 文件
     * @return 父级文件夹
     */
    public static File createFile(File file) {
        File parentFile = file.getParentFile();
        if (!parentFile.exists()) {
            parentFile.mkdirs();
        } else if (!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
            }
        }
        return parentFile;
    }

    public static void transStream(InputStream inputStream, OutputStream outputStream) {
        try {
            byte[] buf = new byte[1024];
            int len;
            while ((len = inputStream.read(buf)) != -1) {
                outputStream.write(buf, 0, len);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            safeClose(inputStream);
            safeClose(outputStream);
        }
    }

    /**
     * 补全末尾分隔符
     *
     * @param path
     * @return
     */
    public static String pathTrim(String path) {
        if (path.startsWith("/") || path.startsWith(File.separator)) {
            path = path.substring(1);
        }
        if (path.endsWith("/") || path.startsWith(File.separator)) {
            path = path.substring(0, path.length() - 1);
        }
        return path;
    }

    public static String filePathJoin(String... path) {
        if (isAnyNull(path)) {
            return "/";
        }
        String collect = Arrays.stream(path).map(Utils::pathTrim).collect(Collectors.joining("/"));
        return path[0].startsWith("/") || path[0].startsWith(File.separator) ? "/" + collect : collect;
    }

    public static String fileName(String path) {
        if (isNull(path)) {
            return "";
        }
        return path.substring(path.lastIndexOf("/") + 1);
    }

    public static String suffix(String fileName) {
        if (isNull(fileName)) {
            return "";
        }
        return fileName.substring(fileName.lastIndexOf(".") + 1);
    }

    /**
     * 流安全关闭
     *
     * @param stream
     */
    public static void safeClose(Closeable stream){
        if (stream != null){
            try {
                stream.close();
                if (stream instanceof GZIPOutputStream){
                    GZIPOutputStream outputStream = (GZIPOutputStream) stream;
                    outputStream.finish();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
